package com.photoeditor.demo.model.image.emoji;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;

import com.common.base.ComponentContext;
import com.photoeditor.demo.model.bean.EmojiBean;
import com.photoeditor.demo.ui.widget.image.emoji.EmojiItem;

import java.io.File;
import java.io.FileFilter;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

/**
 *
 * 这个类用于加载和缓存Emoji Icon
 * 还会缓存编辑Emoji生成的图片
 */
public class EmojiIconManager {

    /**
     * 用于缓存合成图片时的Emoji图片
     * 键是bean.getDownloadId() + File.separator +bean.getName()
     */
    private HashMap<String, Bitmap> mBitmaps;

    /**
     * 用于保存核心数目
     */
    private static int CPU_CORE_NUMBER = 1;

    static{
        try {
            File dir = new File("/sys/devices/system/cpu/");
            if ( dir != null ) {
                File[] files = dir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        if(Pattern.matches("cpu[0-9]", pathname.getName())) {
                            return true;
                        }
                        return false;
                    }
                });
                CPU_CORE_NUMBER =  files.length;
            }

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

	/**
	 * 线程池
	 */
	protected ExecutorService mThreadPool;

	/**
	 * 缓存图片的Map
	 */
	private static LinkedHashMap<String, Bitmap> mThumbnailBitmaps;

    //缓存图片的个数
	private static final int CACHE_SIZE = 56;

	private static final int MSG_END_RUNABLE = 100;
	private static final int MSG_END_RUNABLE_BTN = 101;

	private Handler mHandler = new Handler(Looper.getMainLooper()){
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if(msg.what == MSG_END_RUNABLE){
				ImgBeanHolder holder = (ImgBeanHolder)msg.obj;
				EmojiBean data = (EmojiBean)holder.view.getTag();
				if(holder.bitmap != null && !holder.bitmap.isRecycled()
						&& holder.view != null && data != null && holder.bean != null
						&& holder.bean.getPackageName().equals(data.getPackageName())
                        && holder.bean.getName().equals(data.getName())){//确保是同一个 且一切正常
					holder.view.setIconBitmap(holder.bitmap);
                    mThumbnailBitmaps.put(data.getPackageName() + File.separator + data.getName(), holder.bitmap);
				}
			} else if(msg.what == MSG_END_RUNABLE_BTN){
				ImgBeanHolder holder = (ImgBeanHolder)msg.obj;
				if(holder.bitmap != null && !holder.bitmap.isRecycled()
						&& !TextUtils.isEmpty(holder.pkgName)) {
                    mBitmaps.put(holder.pkgName + File.separator + "iiiii_c", holder.bitmap);
                    Iterator<OnBitmapLoadListener> iterator = listeners.iterator();
                    while (iterator.hasNext()) {
                        OnBitmapLoadListener next = iterator.next();
                        if (TextUtils.equals(next.getPkgName(), holder.pkgName)) {
                            next.onBitmapLoad(holder.pkgName, holder.bitmap);
                            iterator.remove();
                        }
                    }
				}
			}
		};
	};

	private static final ThreadFactory  sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(r, "EmojiIconTask #" + mCount.getAndIncrement());
        }
    };

	public EmojiIconManager(){
        mBitmaps = new HashMap<String, Bitmap>();
		mThreadPool = Executors.newFixedThreadPool(CPU_CORE_NUMBER + 1, sThreadFactory);
        if(mThumbnailBitmaps == null) {
            mThumbnailBitmaps = new LinkedHashMap<String, Bitmap>(CACHE_SIZE, 0.5f, true) {

                private static final long serialVersionUID = 1L;

                @Override
                protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) {
                    if (size() > CACHE_SIZE) {
                        return true;
                    }
                    return super.removeEldestEntry(eldest);
                }
            };
        }
	}

	/**
	 * 加载Icon
	 * @param view
	 * @param data
	 */
	public void loadEmojiThumbnail(EmojiItem view, EmojiBean data){
        if(data.isARType()){
            view.setIconBitmap(data.getContainerBean().getBitmap());
            mThumbnailBitmaps.put(data.getPackageName() + File.separator + data.getName(), data.getContainerBean().getBitmap());
        }else {
            /*try {
                if(data.isType(EmojiPageBean.TYPE_RESOURCES)){
                    Glide.with(ComponentContext.getContext()).load(data.getEmojiId()).crossFade().into(view.mIcon);
                }else {
                    Glide.with().load(data.getEmojiId()).crossFade().into(view.mIcon);
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                Glide.with(ComponentContext.getContext()).load(R.drawable.ic_emoji).crossFade().into(view.mIcon);
            }*/
            Bitmap b = mThumbnailBitmaps.get(data.getPackageName() + File.separator + data.getName());
            if (b != null) {
                view.setIconBitmap(b);
            } else {
                if(!mThreadPool.isShutdown()) {
                    mThreadPool.submit(new IconRunnable(view, data));
                }
            }
        }
	}

	public Bitmap getStickerBtnThumbnail(String pkgName, OnBitmapLoadListener listener) {
        Bitmap b = mBitmaps.get(pkgName + File.separator + "iiiii_c");
        if (b != null) {
            return b;
        } else {
            if(!mThreadPool.isShutdown()) {
                if (listener != null) {
                    listeners.add(listener);
                }
                mThreadPool.submit(new BtnIconRunnable(pkgName));
            }
        }
        return null;
	}

    private HashSet<OnBitmapLoadListener> listeners = new HashSet<>();

	public void clearListener() {
        listeners.clear();
    }

	public interface OnBitmapLoadListener {
	    void onBitmapLoad(String pkgName, Bitmap bitmap);
	    String getPkgName();
    }

    class BtnIconRunnable implements Runnable{

        private final String mPkgName;

        public BtnIconRunnable(String pkgName){
            mPkgName = pkgName;
        }

        @Override
        public void run() {
            try {
                if (!TextUtils.isEmpty(mPkgName)) {
                    StickerApkResource emojiApkBean = LocalStickerData.getInstance().getApkBean().get(mPkgName);
                    Bitmap b = BitmapFactory.decodeResource(emojiApkBean.getRes(), emojiApkBean.getStickerIconId());

                    if (b != null) {
                        Message msg = Message.obtain(mHandler, MSG_END_RUNABLE_BTN);
                        ImgBeanHolder holder = new ImgBeanHolder();
                        holder.bitmap = b;
                        holder.pkgName = mPkgName;
                        msg.obj = holder;
                        mHandler.sendMessage(msg);
                    }
                }
            } catch (Throwable e) {

            }
        }
    }


	class IconRunnable implements Runnable{

		private final WeakReference<EmojiItem> mImageViewReference;
		private EmojiBean mData;

		public IconRunnable(EmojiItem iv, EmojiBean data){
			mImageViewReference = new WeakReference<EmojiItem>(iv);
			mData = data;
		}

		@Override
		public void run() {
            try {
                if (mData != null) {
                    EmojiItem item = mImageViewReference.get();
                    EmojiBean bean = (EmojiBean) item.getTag();
                    if (item != null && bean != null && mData != null
                            && bean.getPackageName().equals(mData.getPackageName()) && bean.getName().equals(mData.getName())) {
                        Bitmap b = null;
                        Resources res = ComponentContext.getContext().getResources();
                        BitmapFactory.Options option = new BitmapFactory.Options();
                        option.inPurgeable = true;
                        option.inInputShareable = true;
                        option.inDither = false;
                        if (bean.isType(EmojiBean.TYPE_RESOURCE)) {
                            option.inSampleSize = 2;
                            b = BitmapFactory.decodeResource(res, bean.getEmojiId(), option);
                        } else if (bean.isType(EmojiBean.TYPE_INSTALL_EMOJI_APK)) {
                            option.inSampleSize = 2;
                            String pkgName = bean.getPackageName();
                            StickerApkResource emojiApkBean = LocalStickerData.getInstance().getApkBean().get(pkgName);
                            b = BitmapFactory.decodeResource(emojiApkBean.getRes(), bean.getEmojiId(), option);
                        } else if (bean.isType(EmojiBean.TYPE_UNINSTALL_APK_PACKAGE) || bean.isType(EmojiBean.TYPE_INSTALL_APK_PACKAGE)) {
                            option.inSampleSize = 3;
                            String pkgName = bean.getPackageName();
                            StickerApkResource emojiApkBean = LocalStickerData.getInstance().getApkBean().get(pkgName);
                            b = BitmapFactory.decodeResource(emojiApkBean.getRes(), bean.getEmojiId(), option);
                        }

                        if(b != null) {
                            Message msg = Message.obtain(mHandler, MSG_END_RUNABLE);
                            ImgBeanHolder holder = new ImgBeanHolder();
                            holder.bitmap = b;
                            holder.view = item;
                            holder.bean = mData;
                            msg.obj = holder;
                            mHandler.sendMessage(msg);
                        }
                    }
                }
            } catch(Throwable e){

            }
        }
	}

    /**
     * 获取bitmap
     * @param bean
     * @return
     */
    public Bitmap getBitmap(EmojiBean bean, Resources resource){
        if(bean == null) return null;
        Bitmap b = mBitmaps.get(bean.getPackageName() + File.separator + bean.getName());
        if(b == null){
            b = BitmapFactory.decodeResource(resource, bean.getEmojiId());
            if(b != null){
                mBitmaps.put(bean.getPackageName() + File.separator +bean.getName(), b);
            }
        }
        return b;
    }

	protected class ImgBeanHolder{
		Bitmap bitmap;
        EmojiItem view;
		EmojiBean bean;
		String pkgName;
	}

    //清除缓存
    public void clearBitmapCache(){
        mBitmaps.clear();
        clearListener();
    }

    /**
     * 一定要注意回收
     */
    public void onDestory(){
        try {
            Iterator iter = mBitmaps.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Bitmap bitmap = (Bitmap) entry.getValue();
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();
                }
            }
            iter = mThumbnailBitmaps.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Bitmap bitmap = (Bitmap) entry.getValue();
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();
                }
            }
            mBitmaps.clear();
            mThreadPool.shutdownNow();
            mThumbnailBitmaps.clear();
            clearListener();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
